﻿/*
 *  Artificial Intelligence Team Project | 120526
 *  Title : The Fugitive
 *  Genre : Smart Phone Game
 *  Member : Jason Park, Jin-Q
 *  All copyright by Jason Park & Jin-Q
 */

using System;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Input.Touch;

namespace TheFugitive
{
    /// <summary>
    /// 메인 코드
    /// </summary>
    public class TheFugitive : Microsoft.Xna.Framework.Game
    {
        #region Fields

        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        // Global content
        private SpriteFont hudFont;
        private SpriteFont menuFont;
        private Texture2D[] backgroundLayer;

        private KeyboardState keyboardState;
        private AccelerometerState accelerometerState;

        private Texture2D winOverlay;
        private Texture2D loseOverlay;
        private Texture2D diedOverlay;

        private Level level;
        private bool wasContinuePressed;

        private bool isStarted = false;
        #endregion

        public TheFugitive()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            graphics.IsFullScreen = true;
            graphics.SupportedOrientations = DisplayOrientation.LandscapeLeft | DisplayOrientation.LandscapeRight;

            // 30 프레임
            TargetElapsedTime = TimeSpan.FromTicks(333333);
            // Extend battery life under lock.
            InactiveSleepTime = TimeSpan.FromSeconds(1);

            Accelerometer.Initialize();
        }

        /// <summary>
        /// 게임이 시작되기 전 필요한 초기화 수행
        /// </summary>
        protected override void Initialize()
        {
            base.Initialize();
        }

        /// <summary>
        /// 필요한 콘텐츠 로드
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // 메인메뉴 폰트
            menuFont = Content.Load<SpriteFont>("Fonts/MenuFont");
            hudFont = Content.Load<SpriteFont>("Fonts/hud");

            // Load overlay textures
            winOverlay = Content.Load<Texture2D>("Overlays/you_win");
            loseOverlay = Content.Load<Texture2D>("Overlays/you_lose");
            diedOverlay = Content.Load<Texture2D>("Overlays/you_died");


            // 메인메뉴 화면의 레이어 구성
            backgroundLayer = new Texture2D[2];
            for (int i = 0; i < backgroundLayer.Length; i++)
            {
                backgroundLayer[i] = Content.Load<Texture2D>("Backgrounds/Background_" + i);
            }

            // 사운드 콘텐츠 로드
            try
            {
                MediaPlayer.IsRepeating = true;
                MediaPlayer.Play(Content.Load<Song>("Sounds/Background1"));
            }
            catch { }

            // 레벨 호출
            LoadNextLevel();
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {

            HandleInput();

            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            keyboardState = Keyboard.GetState();
            TouchPanel.EnabledGestures = GestureType.Tap;

            if (isStarted)
                level.Update(gameTime, keyboardState, accelerometerState, Window.CurrentOrientation);

            TouchCollection currentTouchState = TouchPanel.GetState();
            for (int i = 0; i < currentTouchState.Count; i++)
            {
                TouchLocation currentLocation = currentTouchState[i];
                if (currentLocation.State == TouchLocationState.Pressed)
                {
                    isStarted = true;
                    try
                    {
                        MediaPlayer.IsRepeating = true;
                        MediaPlayer.Play(Content.Load<Song>("Sounds/Background2"));
                    }
                    catch { }
                }
            }

            base.Update(gameTime);
        }

        private void HandleInput()
        {
            // get all of our input states
            keyboardState = Keyboard.GetState();


            //bool continuePressed =
            //    keyboardState.IsKeyDown(Keys.A);

            // Perform the appropriate action to advance the game and
            // to get the player back to playing.
            //if (!wasContinuePressed && continuePressed)
            //{
                
            //     LoadNextLevel(); // level이 하나이기 떄문에 현재는 이게 걍 재시작
                 
            //}

            //wasContinuePressed = continuePressed;

            if (level.life.Count == 0)
            {
                if(keyboardState.IsKeyDown(Keys.Up))
                    ReloadCurrentLevel();
            }
        }

        private void ReloadCurrentLevel()
        {
            //--levelIndex;
            LoadNextLevel();
        }


        /// <summary>
        /// Jason | 120526
        /// 다음 레벨로 이동하는 코드를 추가할 수 있으며 현재는 한 레벨만 호출
        /// </summary>
        private void LoadNextLevel()
        {
            // 레벨 로드
            string levelPath = string.Format("Content/Levels/{0}.txt", 1);
            using (Stream fileStream = TitleContainer.OpenStream(levelPath))
                level = new Level(Services, fileStream, 0);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

            if (isStarted)
            {
                spriteBatch.Begin();

                level.Draw(gameTime, spriteBatch);
                DrawHud();

                spriteBatch.End();
            }
            else
            {
                spriteBatch.Begin();

                for (int i = 0; i < backgroundLayer.Length; i++)
                {
                    spriteBatch.Draw(backgroundLayer[i], Vector2.Zero, Color.White);
                }

                spriteBatch.DrawString(menuFont, "Start", new Vector2(600.0f, 360.0f), Color.White);
                spriteBatch.DrawString(menuFont, "Exit", new Vector2(600.0f, 420.0f), Color.White);

                spriteBatch.End();
            }

            base.Draw(gameTime);
        }

        private void DrawHud()
        {
            Rectangle titleSafeArea = GraphicsDevice.Viewport.TitleSafeArea;
            Vector2 hudLocation = new Vector2(titleSafeArea.X, titleSafeArea.Y);
            Vector2 center = new Vector2(titleSafeArea.X + titleSafeArea.Width / 2.0f,
                                         titleSafeArea.Y + titleSafeArea.Height / 2.0f);

            // Draw time remaining. Uses modulo division to cause blinking when the
            // player is running out of time.
            string timeString = "TIME: " + level.TimeRemaining.Minutes.ToString("00") + ":" + level.TimeRemaining.Seconds.ToString("00");
            Color timeColor;
            
            timeColor = Color.Yellow;

            
            DrawShadowedString(hudFont, timeString, hudLocation, timeColor);

            // Draw score
            //float timeHeight = hudFont.MeasureString(timeString).Y;
            //DrawShadowedString(hudFont, "SCORE: " + level.Score.ToString(), hudLocation + new Vector2(0.0f, timeHeight * 1.2f), Color.Yellow);

            // Determine the status overlay message to show.
            Texture2D status = null;
            if (level.TimeRemaining == TimeSpan.Zero)
            {
                
                status = winOverlay;
                
            }
            else if (level.life.Count == 0)
            {
                status = diedOverlay;
            }

            if (status != null)
            {
                // Draw status message.
                Vector2 statusSize = new Vector2(status.Width, status.Height);
                spriteBatch.Draw(status, center - statusSize / 2, Color.White);
            }
        }

        private void DrawShadowedString(SpriteFont font, string value, Vector2 position, Color color)
        {
            spriteBatch.DrawString(font, value, position + new Vector2(1.0f, 1.0f), Color.Black);
            spriteBatch.DrawString(font, value, position, color);
        }
    }
}
